package com.example.administrator.myapplication.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.RectF;
import android.support.v4.graphics.PathSegment;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ImageView;

import java.util.ArrayList;
import java.util.List;

/**
 * Time:2019/4/27 0027
 * Author:ycf
 */
public class ArrowView extends android.support.v7.widget.AppCompatImageView {

    private Paint paint;
    private Path path;
    private Paint arrowPaint;
    private Path arrowPath;
    private float startX;
    private float startY;
    private float endX;
    private float endY;
    private double angle;

    public ArrowView(Context context) {
        super(context);
        init(context, null, 0);
    }

    public ArrowView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);
    }

    public ArrowView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs, defStyle);
    }

    private void init(Context context, AttributeSet attrs, int defStyle) {
        paint = new Paint();//划线的画笔
        arrowPaint = new Paint();//画箭头的画笔
        arrowPaint.setAntiAlias(true);
        arrowPaint.setColor(Color.RED);
        arrowPaint.setStrokeWidth(5);
        arrowPaint.setStyle(Paint.Style.FILL);//箭头是个实心三角形，所以用fill
        arrowPath = new Path();
        path = new Path();
        paint.setAntiAlias(true);
        paint.setColor(Color.RED);
        paint.setStrokeWidth(5);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeCap(Paint.Cap.ROUND);

        pathSegments = new ArrayList<>();
    }
    @Override
    protected void onDraw(Canvas canvas) {
        setArrowPath();
//        for (PathSegment p: pathSegments) {
//            paint.setAlpha(p.getAlpha());
//            paint.setStrokeWidth(p.getWidth());
//            canvas.drawPath(p.getPath(), paint);
//        }

        canvas.drawPath(path, paint);
        canvas.drawPath(arrowPath, arrowPaint);
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                pathSegments.clear();
                startX = event.getX();
                startY = event.getY();
                return true;
            case MotionEvent.ACTION_MOVE:
                endX=event.getX();
                endY=event.getY();
                clear();
//                getPaths(path);
                setPath(startX,startY,endX,endY);
                break;
                default:
                    break;
        }
        return super.onTouchEvent(event);
    }
    public void setPath(float startX, float startY, float endX, float endY) {
        path.moveTo(startX,startY);
        path.lineTo(endX,endY);
        this.startX = startX;
        this.startY = startY;
        this.endX = endX;
        this.endY = endY;
        Log.d("tag","startX:"+startX+"startY:"+startY+"endX:"+endX+"endY:"+endY);
        invalidate();
    }
    public void clear() {
        path.reset();
        arrowPath.reset();
    }
    /**
     * 画箭头
     */
    public void setArrowPath() {
        double H = 18; // 箭头高度
        double L = 13.5; // 底边的一半

        // 箭头角度
        angle = Math.atan(L / H);
        double arrowLength = Math.sqrt(L * L + H * H); // 箭头的长度
        //箭头就是个三角形，我们已经有一个点了，根据箭头的角度和长度，确定另外2个点的位置
        double[] point1 = rotateVec(endX - startX, endY - startY, angle, arrowLength);
        double[] point2 = rotateVec(endX - startX, endY - startY, -angle, arrowLength);
        double point1_x = endX - point1[0];
        double point1_y = endY - point1[1];
        double point2_x = endX - point2[0];
        double point2_y = endY - point2[1];
        int x3 = (int) point1_x;
        int y3 = (int) point1_y;
        int x4 = (int) point2_x;
        int y4 = (int) point2_y;
        // 画线
        arrowPath.moveTo(endX, endY);
        arrowPath.lineTo(x3, y3);
        arrowPath.lineTo(x4, y4);
        arrowPath.close();
    }
    // 计算
    /**
     * @param diffX  X的差值
     * @param diffY  Y的差值
     * @param angle    箭头的角度（箭头三角形的线与直线的角度）
     * @param arrowLength 箭头的长度
     */
    public double[] rotateVec(float diffX, float diffY, double angle, double arrowLength) {
        double arr[] = new double[2];
        // 下面的是公式，得出的是以滑动出的线段末点为中心点旋转angle角度后,线段起点的坐标，这个旋转后的线段也就是“变长了的箭头的三角形的一条边”
        //推导见注释1
        double x = diffX * Math.cos(angle) - diffY * Math.sin(angle);
        double y = diffX * Math.sin(angle) + diffY * Math.cos(angle);
        double d = Math.sqrt(x * x + y * y);
        //根据相似三角形，得出真正的箭头三角形顶点坐标，这里见注释2
        x = x / d * arrowLength;
        y = y / d * arrowLength;
        arr[0] = x;
        arr[1] = y;
        return arr;
    }

    private class PathSegment{
        Path path;
        float width;
        int alpha;

        public PathSegment(Path path) {
            this.path = path;
        }

        public Path getPath() {
            return path;
        }

        public void setPath(Path path) {
            this.path = path;
        }

        public float getWidth() {
            return width;
        }

        public void setWidth(float width) {
            this.width = width;
        }

        public int getAlpha() {
            return alpha;
        }

        public void setAlpha(int alpha) {
            this.alpha = alpha;
        }

    }

    /**
     * 越小，线条锯齿度越小
     */
    private static final float DEFAULT_SEGMENT_LENGTH = 10F;
    private static final float DEFAULT_WIDTH = 3F;
    private static final float MAX_WIDTH = 45F;
    private List<PathSegment> pathSegments;

    /**
     * 截取path
     * @param path
     */
    private void getPaths(Path path){
        PathMeasure pm = new PathMeasure(path, false);
        float length = pm.getLength();
        int segmentSize = (int) Math.ceil(length / DEFAULT_SEGMENT_LENGTH);
        Path ps = null;
        PathSegment pe = null;
        int nowSize = pathSegments.size();//集合中已经有的
        if(nowSize == 0){
            ps = new Path();
            pm.getSegment(0, length, ps, true);
            pe = new PathSegment(ps);
            pe.setAlpha(255);
            pe.setWidth(DEFAULT_WIDTH);
            pathSegments.add(pe);
        } else{
            for (int i = nowSize; i < segmentSize; i++) {
                ps = new Path();
                pm.getSegment((i - 1) * DEFAULT_SEGMENT_LENGTH - 0.4f, Math.min(i * DEFAULT_SEGMENT_LENGTH, length), ps,  true);
                pe = new PathSegment(ps);
                pe.setAlpha(255);
                pe.setWidth((float) Math.min(MAX_WIDTH, i * 0.3 + DEFAULT_WIDTH));
                pathSegments.add(pe);
            }
        }
    }
}
